from pydantic import BaseModel, validator

# coding: utf-8
from sqlalchemy import BigInteger, CHAR, Column, DateTime, String, event, ForeignKey, Integer
from datetime import datetime
from typing import Optional
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
from models.sys_depts import SysDept
from models.base import Base
from models.sys_depts import SysDeptSchema
from typing import List
from models.sys_posts import SysPostSchema
from models.sys_roles import SysRoleSchema
metadata = Base.metadata


class SysUser(Base):
    def to_dict(self):
        user_dict = {c.name: getattr(self, c.name) for c in self.__table__.columns}
        user_dict['dept'] = self.dept.to_dict() if self.dept else None

        for key, value in user_dict.items():
            if isinstance(value, datetime):
                user_dict[key] = value.isoformat()

        return user_dict

    __tablename__ = 'sys_users'

    id = Column(BigInteger, primary_key=True, comment='用户ID')
    dept_id = Column(Integer, ForeignKey('sys_depts.id'), nullable=False, comment='部门ID')
    user_name = Column(String(30, 'utf8mb4_unicode_ci'), nullable=False, comment='用户账号')
    nick_name = Column(String(30, 'utf8mb4_unicode_ci'), nullable=False, comment='用户昵称')
    user_type = Column(String(2, 'utf8mb4_unicode_ci'), comment='用户类型（00系统用户）')
    email = Column(String(50, 'utf8mb4_unicode_ci'), comment='用户邮箱')
    phone_number = Column(String(11, 'utf8mb4_unicode_ci'), comment='手机号码')
    sex = Column(CHAR(1, 'utf8mb4_unicode_ci'), comment='用户性别（0男 1女 2未知）')
    avatar = Column(String(100, 'utf8mb4_unicode_ci'), comment='头像地址')
    password = Column(String(100, 'utf8mb4_unicode_ci'), comment='密码')
    status = Column(CHAR(1, 'utf8mb4_unicode_ci'), comment='帐号状态（0正常 1停用）')
    del_flag = Column(CHAR(1, 'utf8mb4_unicode_ci'), comment='删除标志（0代表存在 2代表删除）')
    login_ip = Column(String(128, 'utf8mb4_unicode_ci'), comment='最后登录IP')
    login_date = Column(DateTime, comment='最后登录时间')
    create_by = Column(String(64, 'utf8mb4_unicode_ci'), comment='创建者')
    update_by = Column(String(64, 'utf8mb4_unicode_ci'), comment='更新者')
    remark = Column(String(500, 'utf8mb4_unicode_ci'), comment='备注')
    deleted_at = Column(DateTime(timezone=True), nullable=True, comment='删除时间')
    created_at = Column(DateTime, server_default=func.now(), comment='创建时间')
    updated_at = Column(DateTime, onupdate=func.now(), comment='更新时间')

    dept = relationship(SysDept, back_populates="users")


@event.listens_for(SysUser, 'before_update')
def receive_before_update(mapper, connection, target):
    target.updated_at = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M")

@event.listens_for(SysUser, 'before_insert')
def set_created_at(mapper, connection, target):
    if not target.created_at:
        target.created_at = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M")


class SysUserSchema(BaseModel):
    id: int
    dept_id: int
    user_name: str
    nick_name: str
    user_type: str
    email: str
    phone_number: str
    sex: str
    avatar: str
    status: str
    del_flag: str
    login_ip: str
    login_date: Optional[datetime]
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None
    deleted_at: Optional[datetime] = None
    remark: str
    dept: Optional[SysDeptSchema] = None
    roles: Optional[SysRoleSchema]= None
    posts: Optional[SysPostSchema]= None


    class Config:
        orm_mode = True
        json_encoders = {
            datetime: lambda v: v.strftime('%Y-%m-%d %H:%M:%S') if v else None
        }
        from_attributes = True

    @validator('dept', pre=True, always=True)
    def validate_dept(cls, v):
        if isinstance(v, SysDeptSchema):
            return v
        return SysDeptSchema.from_orm(v) if v else None
